package de.tempel.fittslaw.objects;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import de.tempel.fittslaw.regression.EasyRegressionCalculator;
import de.tempel.fittslaw.regression.Line;
import de.tempel.fittslaw.regression.RegressionCalculator;

public class Experiment implements Iterable<Trial> {

	private List<Trial> trials;
	private int currentTrialId;
	private String inputDevice;

	public Experiment(String inputDevice) {
		this.inputDevice = inputDevice;
		init();
	}

	private void init() {
		currentTrialId = 0;

		trials = new ArrayList<Trial>();

		trials.add(new Trial(30, 700, 50));
		trials.add(new Trial(30, 30, 10));
		trials.add(new Trial(30, 280, 25));
		trials.add(new Trial(30, 20, 20));
		trials.add(new Trial(30, 500, 40));
		trials.add(new Trial(30, 300, 100));
		trials.add(new Trial(30, 160, 20));
		trials.add(new Trial(30, 680, 15));
		trials.add(new Trial(30, 120, 60));

	}

	public List<Point2D> getIdMtPoints() {
		int i = 1;
		List<Point2D> points = new ArrayList<Point2D>();

		for (Trial t : trials) {

			points.add(new Point2D.Double(t.getIndexOfDifficulty(), t
					.getMovementTime()));

			i++;
		}

		return points;
	}

	public Line calculateRegressionLine() {
		RegressionCalculator rc = new EasyRegressionCalculator();
		List<Point2D> points = getIdMtPoints();
		return rc.calculateRegression(points);
	}

	// IP = meanID/meanMT
	public double calculateIndexOfPerformance() {

		double sumID = 0;
		double sumMT = 0;

		List<Point2D> points = getIdMtPoints();

		for (Point2D point : points) {
			sumID += point.getX();
			sumMT += point.getY();
		}

		double meanID = sumID / points.size();
		double meanMT = sumMT / points.size();

		return meanID / meanMT;
	}

	// IP = 1/b
	public double calculateIndexOfPerformanceIgnoringA() {

		Line l = calculateRegressionLine();

		return 1 / l.getB();
	}

	public boolean hasNext() {
		if (currentTrialId + 1 >= trials.size()) {
			return false;
		}
		return true;
	}

	public Trial next() {
		currentTrialId++;
		Trial currentTrial = getCurrentTrial();
		return currentTrial;
	}

	public void reset(String newInputDevice) {
		this.inputDevice = newInputDevice;
		init();
	}

	public List<Trial> getTrials() {
		return trials;
	}

	public int getCurrentTrialId() {
		return currentTrialId;
	}

	public Trial getCurrentTrial() {
		return trials.get(currentTrialId);
	}

	@Override
	public Iterator<Trial> iterator() {
		return trials.iterator();
	}

	public String getInputDevice() {
		return inputDevice;
	}

	public void setInputDevice(String inputDevice) {
		this.inputDevice = inputDevice;
	}

}
